package stc.skymobi.netty.handler.codec.access;

import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToMessageEncoder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import stc.skymobi.bean.bytebean.core.BeanFieldCodec;
import stc.skymobi.bean.esb.core.EsbHeaderable;
import stc.skymobi.util.ByteUtils;

import java.util.List;


public class NettyAccessEncoder extends MessageToMessageEncoder {

    private static final Logger logger = LoggerFactory.getLogger(NettyAccessEncoder.class);

    private int dumpBytes = 256;
    private boolean isDebugEnabled;
    private BeanFieldCodec esbBeanCodec;

    private int myESBAddr;

    /**
     * @return the myESBAddr
     */
    public int getMyESBAddr() {
        return myESBAddr;
    }

    /**
     * @param myESBAddr the myESBAddr to set
     */
    public void setMyESBAddr(int myESBAddr) {
        this.myESBAddr = myESBAddr;
    }

    /**
     * @return the esbBeanCodec
     */
    public BeanFieldCodec getEsbBeanCodec() {
        return esbBeanCodec;
    }

    /**
     * @param esbBeanCodec the esbBeanCodec to set
     */
    public void setEsbBeanCodec(BeanFieldCodec esbBeanCodec) {
        this.esbBeanCodec = esbBeanCodec;
    }

    @Override
    public void encode(ChannelHandlerContext ctx, Object msg, List out)
            throws Exception {

        byte[] bytes = AccessSignalCodecUtils.encodeSignal(
                (EsbHeaderable) msg, esbBeanCodec, myESBAddr);

        if (null != bytes) {
            if (logger.isDebugEnabled() && isDebugEnabled) {
                logger.debug("channel {} \r\nsend signal {}", ctx.channel(), msg);
            }
            if (logger.isTraceEnabled() && isDebugEnabled) {
                logger.trace("and raw bytes \r\n{}",
                        ByteUtils.bytesAsHexString(bytes, dumpBytes));
            }
        } else {
            logger.error("encode: " + msg + " can not generate byte stream.");
        }
        out.add(Unpooled.wrappedBuffer(bytes));
    }

    public boolean isDebugEnabled() {
        return isDebugEnabled;
    }

    public void setDebugEnabled(boolean isDebugEnabled) {
        this.isDebugEnabled = isDebugEnabled;
    }

    public int getDumpBytes() {
        return dumpBytes;
    }

    /**
     * @param dumpBytes the dumpBytes to set
     */
    public void setDumpBytes(int dumpBytes) {
        this.dumpBytes = dumpBytes;
    }
}
